#include "errdiff.h"

void valid_then_acc(int i, int j, int val, int errCache[IMG_H][IMG_W]) {
    if (0 <= i && i < IMG_H && 0 <= j && j < IMG_W) {
        errCache[i][j] += val;
    }
}

void errdiff(byte gray[IMG_H][IMG_W]) {
    int errCache[IMG_H][IMG_W] = {0};

    for (int i = 0; i < IMG_H; i++) {
        for (int j = 0; j < IMG_W; j++) {
            byte pix = gray[i][j];
            int err = 0;

            // 1. compare with threshold
            gray[i][j] = pix + errCache[i][j] < THRES ? 0 : 0xff;
            // 2. calculate error
            err = pix + errCache[i][j] - gray[i][j];

            err = (err < -127) ? -127 : (err > 127) ? 127 : err;
            int elut_idx = err + 127;
            // 3. diffuse the error
            valid_then_acc(i,   j+1, elut[elut_idx][0], errCache); // right
            valid_then_acc(i+1, j+1, elut[elut_idx][1], errCache); // bottom-right
            valid_then_acc(i+1, j,   elut[elut_idx][2], errCache); // bottom
            valid_then_acc(i+1, j-1, elut[elut_idx][3], errCache); // bottom-left
        }
    }
}
